package com.manager;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.luaj.vm2.script.LuaScriptEngine;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.obj.AbstractScriptContext;
import com.obj.JavaScriptContext;
import com.obj.LuaScriptContext;
import com.utils.FileUtil;

import jdk.nashorn.api.scripting.NashornScriptEngine;

@Service
public class JavaScriptManager {
	private String CONTEXT_NAME = "serverContext";
	@Autowired
	private MongoTemplate playermongoTemplate;
	private Map<String, AbstractScriptContext> scriptMap = new HashMap<>();

	@PostConstruct
	private void init() {
		ScriptEngineManager sem = new ScriptEngineManager();
		NashornScriptEngine javascriptEngine = (NashornScriptEngine) sem.getEngineByName("JavaScript");
		LuaScriptEngine luascriptEngine = (LuaScriptEngine) sem.getEngineByName("luaj");
		List<File> fileList = new ArrayList<File>();
		FileUtil.listDirectory(new File("./scripts"), fileList);
		for (File file : fileList) {
			Reader reader = null;
			try {
				String scriptName = file.getName();
				String scriptEndName = scriptName.substring(scriptName.lastIndexOf(".") + 1);
				reader = new FileReader(file);
				if (scriptEndName.equals("js")) {
					Compilable compilable = (Compilable) javascriptEngine;
					CompiledScript script = compilable.compile(reader);
					scriptMap.put(scriptName, new JavaScriptContext(playermongoTemplate, script, javascriptEngine,LoggerFactory.getLogger(scriptName)));
				} else if (scriptEndName.equals("lua")) {
					Compilable compilable = (Compilable) luascriptEngine;
					CompiledScript script = compilable.compile(reader);
					scriptMap.put(scriptName, new LuaScriptContext(playermongoTemplate, script, luascriptEngine,LoggerFactory.getLogger(scriptName)));
				}
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (ScriptException e) {
				e.printStackTrace();
			} finally {
				try {
					reader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public String excuteScript(String scriptName, Map<String, String[]> parameterMap,String bodyContent) {
		AbstractScriptContext serverContext = scriptMap.get(scriptName);
		if (serverContext == null) {
			return null;
		}
		serverContext.setParam(parameterMap);
		serverContext.body = bodyContent;
		try {
			Bindings bindings = serverContext.getEngine().createBindings();
			bindings.put(CONTEXT_NAME, serverContext);
			CompiledScript compiledScript = serverContext.getCompiledScript();
			Object r = compiledScript.eval(bindings);
			return JSONObject.toJSONString(r);
		} catch (ScriptException e) {
			e.printStackTrace();
		}
		return null;
	}
}
